I was given my first assignment as implementing inplace assignment operator for numpy arrays in Numba. Numba converts jitted code to first a numba intermediate representation which in then lowered to LLVM code, the code to do this transformation is in lowering.py file, there are functions like lower_binop etc which does that, if I find a function for inplace assignment I'll use that otherwise I'll have to write my self.


Report broken link in http://docs.scipy.org/doc/numpy/reference/index.html


Numba intermediate represenation for

@numba.jit(nopython=True)
def add_5(x):
    y = x + 5
    return y

is

---------------------------------IR DUMP: add_5---------------------------------
label 0:
    x = arg(0, name=x)                       ['x']
    $const0.2 = const(int, 5)                ['$const0.2']
    $0.3 = x + $const0.2                     ['$0.3', '$const0.2', 'x']
    del x                                    []
    del $const0.2                            []
    y = $0.3                                 ['$0.3', 'y']
    del $0.3                                 []
    $0.5 = cast(value=y)                     ['$0.5', 'y']
    del y                                    []
    return $0.5                              ['$0.5']
----------------------------IR DUMP: _broadcast_onto----------------------------
label 0:
    src_ndim = arg(0, name=src_ndim)         ['src_ndim']
    src_shape = arg(1, name=src_shape)       ['src_shape']
    dest_ndim = arg(2, name=dest_ndim)       ['dest_ndim']
    dest_shape = arg(3, name=dest_shape)     ['dest_shape']
    $0.3 = src_ndim > dest_ndim              ['$0.3', 'dest_ndim', 'src_ndim']
    branch $0.3, 12, 16                      ['$0.3']
label 12:
    del src_shape                            []
    del src_ndim                             []
    del dest_shape                           []
    del dest_ndim                            []
    del $0.3                                 []
    $const12.1 = const(int, 0)               ['$const12.1']
    $12.2 = cast(value=$const12.1)           ['$12.2', '$const12.1']
    del $const12.1                           []
    return $12.2                             ['$12.2']
label 16:
    del $0.3                                 []
    $const16.1 = const(int, 0)               ['$const16.1']
    src_index = $const16.1                   ['$const16.1', 'src_index']
    del $const16.1                           []
    $16.4 = dest_ndim - src_ndim             ['$16.4', 'dest_ndim', 'src_ndim']
    del dest_ndim                            []
    dest_index = $16.4                       ['$16.4', 'dest_index']
    del $16.4                                []
    jump 32                                  []
label 32:
    jump 35                                  []
label 35:
    $35.3 = src_index < src_ndim             ['$35.3', 'src_index', 'src_ndim']
    branch $35.3, 47, 163                    ['$35.3']
label 47:
    $47.3 = getitem(index=src_index, value=src_shape) ['$47.3', 'src_index', 'src_shape']
    src_dim_size = $47.3                     ['$47.3', 'src_dim_size']
    del $47.3                                []
    $47.6 = getitem(index=dest_index, value=dest_shape) ['$47.6', 'dest_index', 'dest_shape']
    dest_dim_size = $47.6                    ['$47.6', 'dest_dim_size']
    del $47.6                                []
    $const47.8 = const(int, 1)               ['$const47.8']
    $47.9 = dest_dim_size != $const47.8      ['$47.9', '$const47.8', 'dest_dim_size']
    del $const47.8                           []
    branch $47.9, 79, 115                    ['$47.9']
label 79:
    del $47.9                                []
    $79.3 = src_dim_size != dest_dim_size    ['$79.3', 'dest_dim_size', 'src_dim_size']
    del dest_dim_size                        []
    branch $79.3, 91, 140                    ['$79.3']
label 91:
    $const91.2 = const(int, 1)               ['$const91.2']
    $91.3 = src_dim_size != $const91.2       ['$91.3', '$const91.2', 'src_dim_size']
    del $const91.2                           []
    branch $91.3, 103, 140                   ['$91.3']
label 103:
    del src_shape                            []
    del src_ndim                             []
    del src_index                            []
    del src_dim_size                         []
    del dest_shape                           []
    del $91.3                                []
    del $79.3                                []
    del $35.3                                []
    $const103.2 = const(int, 1)              ['$const103.2']
    $103.3 = dest_index + $const103.2        ['$103.3', '$const103.2', 'dest_index']
    del dest_index                           []
    del $const103.2                          []
    $103.4 = unary(fn=-, value=$103.3)       ['$103.3', '$103.4']
    del $103.3                               []
    $103.5 = cast(value=$103.4)              ['$103.4', '$103.5']
    del $103.4                               []
    return $103.5                            ['$103.5']
label 115:
    del dest_dim_size                        []
    del $47.9                                []
    $const115.2 = const(int, 1)              ['$const115.2']
    $115.3 = src_dim_size != $const115.2     ['$115.3', '$const115.2', 'src_dim_size']
    del $const115.2                          []
    branch $115.3, 127, 140                  ['$115.3']
label 127:
    dest_shape[dest_index] = src_dim_size    ['dest_index', 'dest_shape', 'src_dim_size']
    del src_dim_size                         []
    jump 140                                 []
label 140:
    del src_dim_size                         []
    del $79.3                                []
    del $115.3                               []
    $const140.2 = const(int, 1)              ['$const140.2']
    $140.3 = inplace_binop(lhs=src_index, rhs=$const140.2, fn=+) ['$140.3', '$const140.2', 'src_index']
    del $const140.2                          []
    src_index = $140.3                       ['$140.3', 'src_index']
    del $140.3                               []
    $const140.5 = const(int, 1)              ['$const140.5']
    $140.6 = inplace_binop(lhs=dest_index, rhs=$const140.5, fn=+) ['$140.6', '$const140.5', 'dest_index']
    del $const140.5                          []
    dest_index = $140.6                      ['$140.6', 'dest_index']
    del $140.6                               []
    jump 35                                  []
label 163:
    del src_shape                            []
    del src_ndim                             []
    del src_index                            []
    del dest_shape                           []
    del $91.3                                []
    del $35.3                                []
    jump 164                                 []
label 164:
    $164.2 = cast(value=dest_index)          ['$164.2', 'dest_index']
    del dest_index                           []
    return $164.2                            ['$164.2']

Yeah so I asked for help from Antoine and told that I can do the inplace addition as np.add(x, y, out=x) which sounds good. He asked me to look at register_binary_operator_kernel() in targets/npyimpl


There is a function numpy_ufunc_kernel which implements these ufunc it also has a keyword argument as explicit_output=True but no function uses that operator. After addition operation is called probably passed to an assignment operator, or maybe not?


Cool,